//
// Created by liuping on 2019/1/4.
//

#pragma once

#include <vector>
#include "worker.h"
#include "thread/thread_group.h"

template <typename MsgType>
class WorkerGroup {
 public:
    explicit WorkerGroup(int worker_num);
    using msg_type = MsgType;

    void StopAll() {
        worker_group_.StopAll();
    }

    CoTask &Co(size_t id) {
        if(workers_.size() <= id) {
            throw std::logic_error("in Co WorkerGroup. index out!");
        }
        return workers_[id].co_task_;
    }
    DoubleQueue<MsgType> &Msg(size_t id) {
        if(workers_.size() <= id) {
            throw std::logic_error("in Msg WorkerGroup. index out!");
        }
        return workers_[id].msg_queue_;
    }
 private:
    std::vector<Worker<MsgType>> workers_;
    ThreadGroup worker_group_;
};

template <typename MsgType>
WorkerGroup<MsgType>::WorkerGroup(int worker_num) : workers_(worker_num) {
    for (auto &work : workers_) {
        worker_group_.AddTaskTick(std::bind(&DoubleQueue<MsgType>::OnProc, &work.msg_queue_));
    }
}